package com.myk.game.gobangchess.rooms.oldrooms;

import com.myk.game.gobangchess.constants.BoardStyleData;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.CustomBottom;
import com.myk.game.gobangchess.DataManager;
import com.myk.game.gobangchess.Room;
import com.myk.game.gobangchess.signs.AroundSign;
import com.myk.game.gobangchess.signs.TextSign;
import com.myk.game.gobangchess.signs.LineSign;

import java.util.ArrayList;
import java.util.List;


public class ScoreGoBangRoom extends Room {

    public ScoreGoBangRoom(String roomName) {
        super(roomName, "\t\t积分五子棋，轮流落子，领先两个连五获胜。", "积分五子棋", BoardStyleData.getGoBangStyle(15, 15), true, true);
    }

    @Override
    public String getRuleText() {
        return "黑白轮流落子，可停一手\n"+
        "双方都停一手时立即结束\n"+
        "每形成一个连五，得1分\n"+
        "【获胜条件】：\n"+
        "领先两分或终局时分更高\n"+
        "【默认规则】：\n"+
        "终局时同分，判和棋\n"+
        "【专业规则】：\n"+
        "黑棋不能长连，白棋允许一次长连\n"+
        "终局时同分，偶数黑胜、奇数白胜";
    }
    List<LineSign>lineSigns=new ArrayList<LineSign>();
    boolean[][][] moveable = new boolean[15][15][2];
    final int size=15;
    int[] moveableCount = { 0, 0 };
    boolean isPro;
    int wPro, bPro;
    boolean wConnect6=false;
    void realStart() {
        player_black.clearCustomBottom();
        player_black.dispatchCustomBottom();
        player_white.clearCustomBottom();
        player_white.dispatchCustomBottom();
        noticeBlackMove();
    }

    void tryNormalStart() {
        if (wPro != 0 || bPro != 0)
            return;
        isPro = false;
        realStart();
    }

    void tryProStart() {
        if (wPro != 1 || bPro != 1)
            return;
        isPro = true;
        wConnect6=false;
        gameTip="白方还可长连一次";
        realStart();
    }

    boolean passed;

    void over() {
        if (blackScore > whiteScore) {
            doOver(WinMode.BLACK_WIN,
                    player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
        } else if (whiteScore > blackScore) {
            doOver(WinMode.WHITE_WIN,
                    player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
        } else if (isPro) {
            if (blackScore%2==0) {
                doOver(WinMode.BLACK_WIN,
                player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
            } else {
                doOver(WinMode.WHITE_WIN,
                player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
            }
        }else{
            doOver(WinMode.BOTH_DRAW,player_black.getNickNameOrTemp() + "-黑棋战平" + player_white.getNickNameOrTemp() + "-白棋");
        }
    }

    public void noticeBlackMove() {
        super.noticeBlackMove();
        player_white.clearCustomBottom();
        player_white.dispatchCustomBottom();
        player_black.clearCustomBottom();
        player_black.registerCustomBottom(BPass);
        player_black.dispatchCustomBottom();
    }

    public void noticeWhiteMove() {
        super.noticeWhiteMove();
        player_black.clearCustomBottom();
        player_black.dispatchCustomBottom();
        player_white.clearCustomBottom();
        player_white.registerCustomBottom(WPass);
        player_white.dispatchCustomBottom();
    }

    CustomBottom BNormal = new CustomBottom(this, "默认规则", (player) -> {
        bPro = 0;
        tryNormalStart();
        noticeAllBroadcast("黑方选择了默认规则");
    }), BPro = new CustomBottom(this, "专业规则", (player) -> {
        bPro = 1;
        tryProStart();
        noticeAllBroadcast("黑方选择了专业规则");
    }), WNormal = new CustomBottom(this, "默认规则", (player) -> {
        wPro = 0;
        tryNormalStart();
        noticeAllBroadcast("白方选择了默认规则");
    }), WPro = new CustomBottom(this, "专业规则", (player) -> {
        wPro = 1;
        tryProStart();
        noticeAllBroadcast("白方选择了专业规则");
    }), BPass = new CustomBottom(this, "让一手", (player) -> {
        if (passed) {
            over();
        } else {
            passed = true;
            noticeAllBroadcast("黑方选择让一手");
            noticeWhiteMove();
        }
    }), WPass = new CustomBottom(this, "让一手", (player) -> {
        if (passed) {
            over();
        } else {
            passed = true;
            noticeAllBroadcast("白方选择让一手");
            noticeBlackMove();
        }
    });
    final static int[][] dxdy = {
            { 1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 }
    };

    @Override
    public void doStart() {
        DataManager.noticeAllGameStart(player_black, player_white, roomName);
        overFlag = 1;// 重置结束状态：对弈进行中未结束
        playingStartTime = System.currentTimeMillis(); // 重置对弈开始时间
        resetGrids();
        preHistory();
        player_black.clearCustomBottom();
        player_black.registerCustomBottom(BPro);
        player_black.registerCustomBottom(BNormal);
        player_black.dispatchCustomBottom();
        player_white.clearCustomBottom();
        player_white.registerCustomBottom(WPro);
        player_white.registerCustomBottom(WNormal);
        player_white.dispatchCustomBottom();
    }

    @Override
    public void resetGrids() {
        super.resetGrids();
        moveableCount[0]=moveableCount[1]=225;
        passed=false;
        lineSigns.clear();
        blackScore = 0;
        whiteScore = 0;
        wPro = -1;
        bPro = -1;
        for (int i = 0; i < 15; i++) {
            for (int j = 0; j < 15; j++) {
                moveable[i][j][0] = moveable[i][j][1] = true;
            }
        }
    }
    @Override
    public void doOver(int winMode, String winMsg){
        if(player_black!=null){
            player_black.clearCustomBottom();
            player_black.dispatchCustomBottom();
        }
        if(player_white!=null){
            player_white.clearCustomBottom();
            player_white.dispatchCustomBottom();
        }
        super.doOver(winMode,winMsg);
    }
    @Override
    public void doRule(int row, int col, int value) {
        if (curGrids[row][col] == 0 && ((!isPro) || moveable[row][col][value - 1]||(value==2&&!wConnect6))) {
            signList.clear();
            List<Integer> ids = new ArrayList<>();
            ids.add(getIndex(row, col));
            signList.add(new AroundSign(ids, "#00000000", "#6600FF00", 1.2f));
            curGrids[row][col] = value; // 实际落子
            passed=false;
            stepAdd(); // 步数统计加增加
            if(moveable[row][col][value-1])
                moveableCount[value - 1]--;
            else{
                if(isPro){
                    wConnect6=true;
                    gameTip="白方不能再长连了";
                }
            }
            for (int i = 0; i < 4; i++) {
                int l = 1, j = 1, k = -1;
                boolean jmax=false,kmin=false;
                for (;; j++) {
                    final int x = row + dxdy[i][0] * j;
                    final int y = col + dxdy[i][1] * j;
                    if (x < 0 || x >= size || y < 0 || y >= size ){
                        jmax=true;
                        break;
                    }
                    if(curGrids[x][y] != value) {
                        break;
                    }
                    l++;
                }
                for (;; k--) {
                    final int x = row + dxdy[i][0] * k;
                    final int y = col + dxdy[i][1] * k;
                    if (x < 0 || x >= size || y < 0 || y >= size ){
                        kmin=true;
                        break;
                    }
                    if(curGrids[x][y] != value) {
                        break;
                    }
                    l++;
                }
                if (l == 5) {
                    if (value == 1){
                        blackScore++;
                        lineSigns.add(new LineSign(getIndex(row + dxdy[i][0] * (j-1), col + dxdy[i][1] * (j-1)), getIndex(row + dxdy[i][0] * (k+1), col + dxdy[i][1] * (k+1)), "#B2B2B2B2", 0));
                    }
                    else{
                        whiteScore++;
                        lineSigns.add(new LineSign(getIndex(row + dxdy[i][0] * (j-1), col + dxdy[i][1] * (j-1)), getIndex(row + dxdy[i][0] * (k+1), col + dxdy[i][1] * (k+1)), "#B24C4C4C", 0));
                    }
                }
                if (isPro) {
                    int s=j+1,e=k-1;
                    if(!jmax)
                    for (;; s++) {
                        final int x = row + dxdy[i][0] * s;
                        final int y = col + dxdy[i][1] * s;
                        if (x < 0 || x >= size || y < 0|| y >= size||curGrids[x][y] != value) {
                            s--;
                            if(s-k>=6){
                                final int x1 = row + dxdy[i][0] * j;
                                final int y1 = col + dxdy[i][1] * j;
                                if (moveable[x1][y1][value - 1]) {
                                    moveable[x1][y1][value - 1] = false;
                                    moveableCount[value - 1]--;
                                }
                            }
                            break;
                        }
                    }
                    if(!kmin)
                    for (;; e--) {
                        final int x = row + dxdy[i][0] * e;
                        final int y = col + dxdy[i][1] * e;
                        if (x < 0 || x >= size || y < 0|| y >= size||curGrids[x][y] != value) {
                            e++;
                            if(j-e>=6){
                                final int x1 = row + dxdy[i][0] * k;
                                final int y1 = col + dxdy[i][1] * k;
                                if (moveable[x1][y1][value - 1]) {
                                    moveable[x1][y1][value - 1] = false;
                                    moveableCount[value - 1]--;
                                }
                            }
                            break;
                        }
                    }
                }
            }
            if(isPro){
                for(int i=0;i<size;i++){
                    for(int j=0;j<size;j++){
                        if(curGrids[i][j]==0){
                            if(moveable[i][j][0]==false){
                                if(moveable[i][j][1]==false){
                                    signList.add(new TextSign(getIndex(i, j) ,"X", "#FFFF0000"));
                                }else{
                                    signList.add(new TextSign(getIndex(i, j) ,"X", "#FF000000"));
                                }
                            }else if(moveable[i][j][1]==false){
                                if(wConnect6)
                                    signList.add(new TextSign(getIndex(i, j) ,"X", "#FFFFFFFF"));
                                else
                                    signList.add(new TextSign(getIndex(i, j) ,"·", "#FFFFFFFF"));
                            }
                        }
                    }
                }
            }
            for (LineSign l : lineSigns) {
                signList.add(l);
            }
            if (blackScore - whiteScore >= 2) {
                doOver(WinMode.BLACK_WIN,
                        player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
            } else if (whiteScore - blackScore >= 2) {
                doOver(WinMode.WHITE_WIN,
                        player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
            } else if (moveableCount[0] == 0 && moveableCount[1] == 0) {
                if (blackScore > whiteScore) {
                    doOver(WinMode.BLACK_WIN,
                            player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
                } else if (whiteScore > blackScore ) {
                    doOver(WinMode.WHITE_WIN,
                            player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
                }else if(isPro){
                    if (blackScore%2==0) {
                        doOver(WinMode.BLACK_WIN,
                        player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
                    } else {
                        doOver(WinMode.WHITE_WIN,
                        player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
                    }
                }else {
                    doOver(WinMode.BOTH_DRAW,player_black.getNickNameOrTemp() + "-黑棋战平" + player_white.getNickNameOrTemp() + "-白棋");
                }
            } else {
                if (value == 1) {
                    noticeWhiteMove();
                } else {
                    noticeBlackMove();
                }
            }
        }
    }
}
